﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.ServiceProcess;
using System.Threading;
using System.IO;
using System.Windows.Forms;

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

using FundSms.SmsLib;

namespace SmsServer
{
    public class Program : ServiceBase
    {
        private static int ServerPort = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
        private static int ClearTime = Convert.ToInt32(ConfigurationManager.AppSettings["ClearTime"]) * 1000;
        private static int SleepTime = Convert.ToInt32(ConfigurationManager.AppSettings["SleepTime"]);

        private static bool LogToFile = ConfigurationManager.AppSettings["LogToFile"] == "1" ? true : false;

        private static string ServiceRealName = ConfigurationManager.AppSettings["ServiceName"];
        private static string ServiceDisPlayName = ConfigurationManager.AppSettings["ServiceDisPlayName"];
        private static string ServiceDescription = ConfigurationManager.AppSettings["ServiceDescription"];

        //服务所在路径
        private static string ServicePath = Application.ExecutablePath;
        private static string ServiceDirectory = Path.GetDirectoryName(ServicePath);

        //锁定开关
        private static object obj = new object();

        //调试开关
        private static int Debug = 0;

        //定时清理控制台
        private static System.Timers.Timer CheckUpdatetimer = new System.Timers.Timer();

        private static TcpServerChannel channel;

        #region 应用程序主入口
        static void Main(string[] args)
        {
            Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

            bool exists = ServiceControl.CheckService(ServiceRealName);

            if (args.Length == 0)
            {
                ServiceBase.Run(new ServiceBase[] { new Program() });
            }
            else
            {
                string parm = args[0].ToLower();

                switch (parm)
                {
                    case "-debug":
                    case "/debug":

                        Debug = 1;

                        if (exists)
                        {
                            ServiceControllerStatus status = ServiceControl.GetServiceStatus(ServiceRealName);

                            if (status != ServiceControllerStatus.Stopped)
                            {
                                Console.WriteLine(GetDateTime() + ServiceRealName + " 服务正在运行，无法进入调试状态。请先停止该服务");
                                Console.ReadLine();
                            }
                            else
                            {
                                InitilizeCompoment();
                            }
                        }
                        else
                        {
                            InitilizeCompoment();
                        }


                        break;

                    case "-install":
                    case "-setup":
                    case "/install":
                    case "/setup":

                        if (exists)
                        {
                            Console.WriteLine(GetDateTime() + ServiceRealName + " 服务已经存在，如果您想升级服务，请先卸载该服务");
                            Console.ReadLine();
                        }
                        else
                        {
                            Console.WriteLine(GetDateTime() + ServicePath);

                            bool result = ServiceControl.InstallService(ServicePath, ServiceRealName, ServiceDisPlayName, ServiceDescription);

                            if (result)
                            {
                                Console.WriteLine(GetDateTime() + "服务安装成功");
                                Console.WriteLine(GetDateTime() + "正在启动服务...");

                                ServiceControl.StartService(ServiceRealName);

                                while (!(ServiceControl.GetServiceStatus(ServiceRealName) == ServiceControllerStatus.Running))
                                {
                                    Thread.Sleep(SleepTime);
                                }

                                Console.WriteLine(GetDateTime() + "服务已经启动");
                            }
                            else
                            {
                                Console.WriteLine(GetDateTime() + "服务安装失败");
                            }

                            Console.ReadLine();
                        }
                        break;

                    case "-uninstall":
                    case "-remove":
                    case "/uninstall":
                    case "/remove":

                        if (!exists)
                        {
                            Console.WriteLine(GetDateTime() + ServiceRealName + " 服务尚未安装");
                        }
                        else
                        {
                            bool result = ServiceControl.UnInstallService(ServiceRealName);

                            if (!result)
                            {
                                Console.WriteLine(GetDateTime() + "服务卸载失败");
                            }
                            else
                            {
                                Console.WriteLine(GetDateTime() + "服务卸载成功");
                            }
                        }

                        Console.ReadLine();

                        break;

                }

            }
        }

        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            Output("未处理A：" + e.Exception.Message, ConsoleColor.Red, true);
        }

        static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is System.Exception)
            {
                Output("未处理P：" + ((System.Exception)e.ExceptionObject).Message, ConsoleColor.Red, true);
            }

        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {

            }

            base.Dispose(disposing);
        }

        public Program()
        {
            base.ServiceName = ServiceRealName;
            base.AutoLog = true;
        }
        #endregion

        #region 初始化服务设置
        protected override void OnStart(string[] args)
        {
            InitilizeCompoment();
        }

        protected override void OnStop()
        {
            //停止定时器
            CheckUpdatetimer.Enabled = false;

            if (channel != null)
            {
                ChannelServices.UnregisterChannel(channel);
            }
           
        }

        #endregion

        #region 应用程序逻辑
        private static void InitilizeCompoment()
        {
            if (Debug == 1)
            {
                Console.Title = ServiceDisPlayName;
            }

            try
            {
                channel = new TcpServerChannel(ServerPort);
                ChannelServices.RegisterChannel(channel, false);
                RemotingConfiguration.RegisterWellKnownServiceType(typeof(FundSms.RemoteObject.RemoteObject), "RemoteObject", WellKnownObjectMode.Singleton);



                Output("服务已经启动",true);

            }
            catch (Exception e)
            {
                Output("服务无法启动", ConsoleColor.Red,true);
                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
            }


            Output("开始等待接收数据...");

            if (Debug == 1)
            {
                Console.ReadLine();
            }
        }
        #endregion

        #region 定时器逻辑

        private static void InitilizeTimer()
        {
            // 循环间隔时间(10分钟)
            CheckUpdatetimer.Interval = ClearTime;
            // 允许Timer执行
            CheckUpdatetimer.Enabled = true;
            // 定义回调
            CheckUpdatetimer.Elapsed += new System.Timers.ElapsedEventHandler(CheckUpdatetimer_Elapsed);
            // 定义多次循环
            CheckUpdatetimer.AutoReset = true;
        }

        static void CheckUpdatetimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Console.Clear();
        }

        #endregion         

        #region 调试辅助逻辑
        private static string GetDateTime()
        {
            return "[" + DateTime.Now.ToString("HH:mm:ss") + "] ";
        }

        private static void Output(string msg)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.WriteLine(GetDateTime() + msg);
                }
            }
        }

        private static void Output(string msg, bool log)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.WriteLine(GetDateTime() + msg);
                }

                if (log)
                {
                    if (LogToFile)
                    {
                        Log.WriteToFile(ServiceDirectory + @"\log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", GetDateTime() + msg);
                    }
                }
            }
        }

        private static void Output(string msg, ConsoleColor color)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.ForegroundColor = color;
                    Console.WriteLine(GetDateTime() + msg);
                    Console.ResetColor();
                }
            }
        }

        private static void Output(string msg, ConsoleColor color, bool log)
        {
            lock (obj)
            {
                if (Debug == 1)
                {
                    Console.ForegroundColor = color;
                    Console.WriteLine(GetDateTime() + msg);
                    Console.ResetColor();
                }

                if (log)
                {
                    if (LogToFile)
                    {
                        Log.WriteToFile(ServiceDirectory + @"\log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", GetDateTime() + msg);
                    }
                }
            }
        }
        #endregion
    }
}
